package com.yichi.detector;

import android.util.Log;

import androidx.annotation.NonNull;

//import com.google.mlkit.vision.face.Face;

import com.google.mlkit.vision.face.Face;

import java.util.ArrayDeque;
import java.util.Iterator;
import java.util.Queue;

public class BlinkDetector {
    // 基础参数
    private static final float BASE_EYE_CLOSE_THRESHOLD = 0.3f;
    private static final long MIN_BLINK_DURATION = 80;   // 最短眨眼时间(ms)
    private static final long MAX_BLINK_DURATION = 600;  // 最长眨眼时间(ms)
    private static final long BLINK_TIMEOUT = 10000;     // 10秒超时
    private static final long STATE_TIMEOUT = 150;       // 状态转换超时

    // 状态枚举
    private enum BlinkState {
        EYES_OPEN,      // 睁眼状态
        EYES_CLOSING,   // 正在闭眼
        EYES_CLOSED,    // 持续闭眼
        EYES_OPENING    // 正在睁眼
    }

    // 状态相关变量
    private BlinkState currentState = BlinkState.EYES_OPEN;
    private long stateEnterTime = 0;
    private long closeStartTime = 0;
    private long openStartTime = 0;

    // 检测参数
    private float dynamicThreshold = BASE_EYE_CLOSE_THRESHOLD;
    private int requiredBlinks = 1;
    private int blinkCounter = 0;
    private long firstBlinkTime = 0;

    // 缓冲队列
    private final Queue<Boolean> eyeStateBuffer = new ArrayDeque<>(5);
    private long lastFaceUpdateTime = 0;

    public boolean checkBlink(@NonNull Face face) {
        long currentTime = System.currentTimeMillis();
        updateDynamicThreshold(face);
        lastFaceUpdateTime = currentTime;

        // 获取稳定状态（5帧中有3帧闭合视为有效）
        boolean currentState = isEyesClosed(face);
        updateStateBuffer(currentState);
        boolean stableState = checkStableState();

        // 状态机处理
        handleStateTransition(currentTime, stableState);

        // 超时处理
        handleTimeouts(currentTime);

        return blinkCounter >= requiredBlinks;
    }

    private void updateDynamicThreshold(Face face) {
        // 根据人脸大小调整阈值（示例值需校准）
        float faceWidth = face.getBoundingBox().width();
        float screenWidth = 1080f; // 假设屏幕宽度
        dynamicThreshold = BASE_EYE_CLOSE_THRESHOLD * (1 + (faceWidth/screenWidth)*0.2f);
    }

    private boolean isEyesClosed(Face face) {
        Float left = face.getLeftEyeOpenProbability();
        Float right = face.getRightEyeOpenProbability();

        // 允许单眼闭合检测
        boolean leftClosed = (left != null && left < dynamicThreshold);
        boolean rightClosed = (right != null && right < dynamicThreshold);

        return leftClosed || rightClosed;
    }

    private void updateStateBuffer(boolean currentState) {
        eyeStateBuffer.offer(currentState);
        if (eyeStateBuffer.size() > 5) {
            eyeStateBuffer.poll();
        }
    }

    private boolean checkStableState() {
        int closeCount = 0;
        for (Boolean state : eyeStateBuffer) {
            if (state) closeCount++;
        }
        return closeCount >= 3;
    }

    private void handleStateTransition(long currentTime, boolean stableState) {
        switch (currentState) {
            case EYES_OPEN:
                if (stableState) {
                    transitionToState(BlinkState.EYES_CLOSING, currentTime);
                    closeStartTime = currentTime;
                }
                break;

            case EYES_CLOSING:
                if (!stableState) {
                    transitionToState(BlinkState.EYES_OPEN, currentTime);
                } else if (currentTime - stateEnterTime > 50) {
                    transitionToState(BlinkState.EYES_CLOSED, currentTime);
                }
                break;

            case EYES_CLOSED:
                if (!stableState) {
                    transitionToState(BlinkState.EYES_OPENING, currentTime);
                    openStartTime = currentTime;
                }
                break;

            case EYES_OPENING:
                if (stableState) {
                    transitionToState(BlinkState.EYES_CLOSED, currentTime);
                } else if (currentTime - stateEnterTime > 50) {
                    validateBlink(currentTime);
                    transitionToState(BlinkState.EYES_OPEN, currentTime);
                }
                break;
        }
    }

    private void validateBlink(long openEndTime) {
        long blinkDuration = openEndTime - closeStartTime;

        if (blinkDuration >= MIN_BLINK_DURATION &&
                blinkDuration <= MAX_BLINK_DURATION) {

            blinkCounter++;
            if (blinkCounter == 1) {
                firstBlinkTime = System.currentTimeMillis();
            }
            Log.d("BlinkDebug", "有效眨眼检测，当前计数: " + blinkCounter);
        }
    }

    private void transitionToState(BlinkState newState, long time) {
        currentState = newState;
        stateEnterTime = time;
    }

    private void handleTimeouts(long currentTime) {
        // 总超时重置
        if (blinkCounter > 0 && (currentTime - firstBlinkTime) > BLINK_TIMEOUT) {
            reset();
            Log.d("BlinkDebug", "检测超时重置");
        }

        // 状态转换超时
        if (currentTime - stateEnterTime > STATE_TIMEOUT) {
            transitionToState(BlinkState.EYES_OPEN, currentTime);
            Log.d("BlinkDebug", "状态超时重置");
        }

        // 人脸丢失超时（1秒无更新）
        if (currentTime - lastFaceUpdateTime > 1000) {
            reset();
            Log.d("BlinkDebug", "人脸丢失重置");
        }
    }

    public void reset() {
        currentState = BlinkState.EYES_OPEN;
        blinkCounter = 0;
        firstBlinkTime = 0;
        eyeStateBuffer.clear();
        stateEnterTime = 0;
    }
}
